package com.ruoyi.agriculture.pestdisease.controller;

import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.agriculture.pestdisease.domain.PestDisease;
import com.ruoyi.agriculture.pestdisease.service.IPestDiseaseService;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;

/**
 * 病虫害管理Controller - Java 8 兼容版本
 *
 * @author ruoyi
 * @date 2025-07-24
 */
@RestController
@RequestMapping("/pestdisease/pestdisease")
public class PestDiseaseController extends BaseController
{
    @Autowired
    private IPestDiseaseService pestDiseaseService;

    /**
     * 查询病虫害管理列表
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:list')")
    @GetMapping("/list")
    public TableDataInfo list(PestDisease pestDisease)
    {
        startPage();
        List<PestDisease> list = pestDiseaseService.selectPestDiseaseList(pestDisease);
        return getDataTable(list);
    }

    /**
     * 🔥 新增：获取所有作物分类 - 必须放在 /{id} 之前避免路由冲突
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:list')")
    @GetMapping("/categories")
    public AjaxResult getCategories()
    {
        try {
            logger.info("🔍 获取作物分类列表");

            // 获取所有不同的分类ID
            List<PestDisease> allPests = pestDiseaseService.selectPestDiseaseList(new PestDisease());

            // Java 8 兼容的分组方式
            Map<Long, List<PestDisease>> groupedByCategory = new HashMap<>();
            for (PestDisease pest : allPests) {
                Long categoryId = pest.getCategoryId();
                if (!groupedByCategory.containsKey(categoryId)) {
                    groupedByCategory.put(categoryId, new ArrayList<PestDisease>());
                }
                groupedByCategory.get(categoryId).add(pest);
            }

            Map<Long, Object> categories = new HashMap<>();
            for (Map.Entry<Long, List<PestDisease>> entry : groupedByCategory.entrySet()) {
                Long categoryId = entry.getKey();
                List<PestDisease> pests = entry.getValue();

                Map<String, Object> categoryInfo = new HashMap<>();

                // 推断作物名称（从病虫害名称中提取）
                String cropName = inferCropName(pests);
                categoryInfo.put("name", cropName);
                categoryInfo.put("count", pests.size());

                // 统计病害、虫害和生理性病害数量
                long diseaseCount = 0;
                long pestCount = 0;
                long physiologicalDiseaseCount = 0;
                for (PestDisease pest : pests) {
                    if ("病害".equals(pest.getType())) {
                        diseaseCount++;
                    } else if ("虫害".equals(pest.getType())) {
                        pestCount++;
                    } else if ("生理性病害".equals(pest.getType())) {
                        physiologicalDiseaseCount++;
                    }
                }
                categoryInfo.put("diseases", diseaseCount);
                categoryInfo.put("pests", pestCount);
                categoryInfo.put("physiologicalDiseases", physiologicalDiseaseCount);

                categories.put(categoryId, categoryInfo);
            }

            logger.info("✅ 找到{}个作物分类", categories.size());
            return success(categories);
        } catch (Exception e) {
            logger.error("💥 获取作物分类失败", e);
            return error("获取分类失败: " + e.getMessage());
        }
    }

    /**
     * 🔥 新增：根据作物类型获取病虫害分类列表 - 必须放在 /{id} 之前避免路由冲突
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:list')")
    @GetMapping("/listByCategory")
    public AjaxResult listByCategory(@RequestParam(value = "categoryId", required = false) Long categoryId)
    {
        try {
            logger.info("🔍 接收到按分类查询病虫害请求，分类ID: {}", categoryId);

            PestDisease queryParam = new PestDisease();
            if (categoryId != null) {
                queryParam.setCategoryId(categoryId);
            }

            List<PestDisease> allPests = pestDiseaseService.selectPestDiseaseList(queryParam);
            logger.info("🔍 查询到病虫害数据总数: {}", allPests.size());

            // 按类型分组：病害 vs 虫害 vs 生理性病害 - Java 8 兼容写法
            Map<String, List<PestDisease>> groupedByType = new HashMap<>();
            for (PestDisease pest : allPests) {
                String type = pest.getType();
                if (!groupedByType.containsKey(type)) {
                    groupedByType.put(type, new ArrayList<PestDisease>());
                }
                groupedByType.get(type).add(pest);
            }

            // 构造返回数据
            Map<String, Object> result = new HashMap<>();
            List<PestDisease> diseases = groupedByType.containsKey("病害") ? groupedByType.get("病害") : new ArrayList<PestDisease>();
            List<PestDisease> pests = groupedByType.containsKey("虫害") ? groupedByType.get("虫害") : new ArrayList<PestDisease>();
            List<PestDisease> physiologicalDiseases = groupedByType.containsKey("生理性病害") ? groupedByType.get("生理性病害") : new ArrayList<PestDisease>();

            result.put("diseases", diseases);
            result.put("pests", pests);
            result.put("physiologicalDiseases", physiologicalDiseases);
            result.put("diseaseCount", diseases.size());
            result.put("pestCount", pests.size());
            result.put("physiologicalDiseaseCount", physiologicalDiseases.size());
            result.put("total", allPests.size());

            logger.info("✅ 返回数据: 病害{}种, 虫害{}种, 生理性病害{}种",
                    result.get("diseaseCount"), result.get("pestCount"), result.get("physiologicalDiseaseCount"));

            return success(result);
        } catch (Exception e) {
            logger.error("💥 按分类查询病虫害失败", e);
            return error("查询失败: " + e.getMessage());
        }
    }

    /**
     * 🔥 新增：根据关键词搜索病虫害 - 必须放在 /{id} 之前避免路由冲突
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:list')")
    @GetMapping("/search")
    public AjaxResult searchPests(@RequestParam("keyword") String keyword)
    {
        try {
            logger.info("🔍 搜索病虫害，关键词: {}", keyword);

            if (keyword == null || keyword.trim().isEmpty()) {
                return error("搜索关键词不能为空");
            }

            PestDisease queryParam = new PestDisease();
            queryParam.setName(keyword.trim()); // MyBatis会处理模糊查询

            List<PestDisease> results = pestDiseaseService.selectPestDiseaseList(queryParam);

            logger.info("✅ 搜索到{}条结果", results.size());
            return success(results);
        } catch (Exception e) {
            logger.error("💥 搜索病虫害失败", e);
            return error("搜索失败: " + e.getMessage());
        }
    }

    /**
     * 根据病虫害名称获取详细信息 - 必须放在 /{id} 之前避免路由冲突
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:query')")
    @GetMapping("/query")
    public AjaxResult getInfoByName(@RequestParam("name") String name)
    {
        try {
            logger.info("🔍 接收到根据名称查询病虫害的请求，名称: {}", name);

            if (name == null || name.trim().isEmpty()) {
                logger.warn("❌ 病虫害名称为空");
                return error("病虫害名称不能为空");
            }

            String trimmedName = name.trim();
            logger.info("🔍 开始查询病虫害，处理后名称: {}", trimmedName);

            PestDisease pestDisease = pestDiseaseService.selectPestDiseaseByName(trimmedName);

            if (pestDisease == null) {
                logger.warn("❌ 未找到名称为 '{}' 的病虫害信息", trimmedName);
                return error("未找到名称为 '" + trimmedName + "' 的病虫害信息");
            }

            logger.info("✅ 成功查询到病虫害信息: ID={}, 名称={}, 类型={}",
                    pestDisease.getId(), pestDisease.getName(), pestDisease.getType());

            return success(pestDisease);
        } catch (Exception e) {
            logger.error("💥 根据名称查询病虫害信息失败，名称: " + name, e);
            return error("查询失败，请稍后重试: " + e.getMessage());
        }
    }

    /**
     * 🔥 获取病虫害管理详细信息 - 放在最后，避免与具体路径冲突
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        logger.info("🔍 接收到根据ID查询病虫害的请求，ID: {}", id);
        return success(pestDiseaseService.selectPestDiseaseById(id));
    }

    /**
     * 导出病虫害管理列表
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:export')")
    @Log(title = "病虫害管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, PestDisease pestDisease)
    {
        List<PestDisease> list = pestDiseaseService.selectPestDiseaseList(pestDisease);
        ExcelUtil<PestDisease> util = new ExcelUtil<PestDisease>(PestDisease.class);
        util.exportExcel(response, list, "病虫害管理数据");
    }

    /**
     * 新增病虫害管理
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:add')")
    @Log(title = "病虫害管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody PestDisease pestDisease)
    {
        return toAjax(pestDiseaseService.insertPestDisease(pestDisease));
    }

    /**
     * 修改病虫害管理
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:edit')")
    @Log(title = "病虫害管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody PestDisease pestDisease)
    {
        return toAjax(pestDiseaseService.updatePestDisease(pestDisease));
    }

    /**
     * 删除病虫害管理
     */
    @PreAuthorize("@ss.hasPermi('pestdisease:pestdisease:remove')")
    @Log(title = "病虫害管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(pestDiseaseService.deletePestDiseaseByIds(ids));
    }

    /**
     * 🔧 辅助方法：从病虫害列表推断作物名称
     */
    private String inferCropName(List<PestDisease> pests) {
        if (pests.isEmpty()) return "未知作物";

        String firstName = pests.get(0).getName();
        if (firstName.contains("小麦")) return "小麦";
        if (firstName.contains("玉米")) return "玉米";
        if (firstName.contains("水稻")) return "水稻";
        if (firstName.contains("马铃薯")) return "马铃薯";
        if (firstName.contains("棉花")) return "棉花";

        return "其他作物";
    }
}